/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package net.sf.l2j.gameserver.datatables;

import java.io.File;
import java.util.Map;

import java.util.StringTokenizer;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilderFactory;
import javolution.util.FastMap;
import net.sf.l2j.gameserver.model.L2Skill;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.model.base.ClassId;
import net.sf.l2j.gameserver.templates.skills.L2SkillType;
import org.w3c.dom.Document;
import org.w3c.dom.Node;

/**
 *  @author Flamingo
 */
public class ForgottenScrollsTable
{
    private static Logger _log = Logger.getLogger(SkillTable.class.getName());
    private static ForgottenScrollsTable _instance;
    private Map<Integer, Scroll> _scrolls;

    public static ForgottenScrollsTable getInstance() {
        if (_instance == null)
        {
            _instance = new ForgottenScrollsTable();
        }
        return _instance;
    }

    public int[] getScrollIDS() {
        int[] list = new int[_scrolls.size()];
        int i=0;
        for(Integer key : _scrolls.keySet()){
            list[i] = key;
            i++;
        }
        return list;
    }

    /**
     * Checks if the player is able to learn this skill or not.
     * @param player
     * @param scrollID
     * @return
     */
    public boolean validatePlayer(L2PcInstance player, int scrollID) {
        Scroll s = _scrolls.get(scrollID);
        if (s == null)
        {
            _log.warning("Sorry, info not defined for the Forgotten scroll " +
                    scrollID);
            //Should never happen O.o
            return false;
        }
        if (player == null)
        {
            return false;
        }
        //===CLASS CHECK===//
        boolean classOK = false;
        for (int i = 0; i < s._classes.length; i++)
        {
            if (player.getClassId().equalsOrChildOf(ClassId.values()[s._classes[i]]))
            {
                classOK = true;
                break;
            }
        }
        if (!classOK)
        {
            return false;
        }
        //===SKILLS CHECK==//
        L2Skill[] own = player.getAllSkills();  //Player skills
        for (L2Skill sk : own)
        {
            for (int i : getSkillIds(scrollID))
            {
                //if player already got one of the skills related to this scroll
                if (sk.getId() == i)
                {
                    return false; //the scroll cannot be used
                }
            }
        }
        //===LEVEL CHECK===//
        if (player.getLevel() < s._minLevel)
        {
            return false;
        }
        return true;
    }

    /**
     * @param scrollID The id of the item
     * @return The skill associated to the item
     */
    public int[] getSkillIds(int scrollID) {
        Scroll s = _scrolls.get(scrollID);
        if (s == null)
        {
            _log.warning("Sorry, info not defined for the Forgotten scroll " +
                    scrollID);
            return null;
        }
        return s._skillIds;
    }

    @SuppressWarnings("synthetic-access")
    private ForgottenScrollsTable() {
        _scrolls = new FastMap<Integer, Scroll>();
        StringTokenizer st;
        File file = null;
        try
        {
            file = new File("data/ForgottenScrolls.xml");
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setValidating(false);
            factory.setIgnoringComments(true);
            Document doc = factory.newDocumentBuilder().parse(file);
            Node first = doc.getFirstChild();
            Node n;
            if (first.getNodeName().equals("list"))
            {
                for (int i = 0; i < first.getChildNodes().getLength(); i++)
                {
                    try
                    {
                        n = first.getChildNodes().item(i);
                        if (n.getNodeName().equals("scroll"))
                        {
                            Scroll s = new Scroll();
                            s._name = n.getAttributes().getNamedItem("name").getNodeValue();
                            s._minLevel = Integer.valueOf(n.getAttributes().getNamedItem("minLevel").getNodeValue());
                            s._itemId = Integer.valueOf(n.getAttributes().getNamedItem("itemId").getNodeValue());
                            st = new StringTokenizer(n.getAttributes().getNamedItem("skillIds").getNodeValue(), ",");
                            s._skillIds=new int[st.countTokens()];
                            boolean ok = true;
                            for (int j = 0; j < s._skillIds.length; j++)
                            {
                                s._skillIds[j] = Integer.valueOf(st.nextToken());
                                L2Skill skill = SkillTable.getInstance().getInfo(s._skillIds[j], 1);
                                if (skill == null || skill.getSkillType() ==
                                        L2SkillType.NOTDONE)
                                {
                                    ok = false;
                                }
                            }
                            st = new StringTokenizer(n.getAttributes().getNamedItem("classes").getNodeValue(), ",");
                            s._classes = new int[st.countTokens()];
                            for (int j = 0; j < st.countTokens(); j++)
                            {
                                s._classes[j] = Integer.valueOf(st.nextToken());
                            }
                            //Wont put this scroll into the list if one of the skills is not working
                            if (ok)
                            {
                                _scrolls.put(s._itemId, s);
                            }else{
                            }
                        }
                    } catch (Exception e)
                    {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception i)
        {
            i.printStackTrace();
        }
        _log.info("ForgottenScrollsTable: Loaded " + _scrolls.size() +
                " Forgotten Scrolls");
    }

    public static void reload() {
        _instance = new ForgottenScrollsTable();
    }

    private class Scroll
    {

        String _name;
        int[] _classes;
        int _minLevel;
        int _itemId;
        int[] _skillIds;
    }
}
